package com.mini.gateway.core.modules.log.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mini.gateway.core.modules.log.entity.ApiLog;
import com.mini.gateway.core.modules.log.mapper.ApiLogMapper;
import com.mini.gateway.core.modules.log.dto.ApiLogDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ApiLogService
 * 接口调用日志Service
 *
 */
@Slf4j
@Component
public class ApiLogService {

    @Autowired
    private ApiLogMapper apiLogMapper;

    /**
     * 分页查询记录
     * @param pageable
     * @return
     */
    public Page<ApiLogDTO> getPage(Page pageable, String routeId, String type, Integer responseCode, LocalDateTime startTime, LocalDateTime endTime) {
        Integer responseCodeStart = null;
        Integer responseCodeEnd = null;
        if (responseCode != null) {
            responseCodeStart = responseCode * 100;
            responseCodeEnd = (responseCode + 1) * 100 - 1;
        }
        QueryWrapper<ApiLog> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(StringUtils.isNotBlank(routeId), ApiLog::getRouteId, routeId)
                .eq(StringUtils.isNotBlank(type), ApiLog::getMethod, type)
                .between(responseCode != null, ApiLog::getResponseCode, responseCodeStart, responseCodeEnd)
                .between(startTime != null && endTime != null, ApiLog::getStartTime, startTime, endTime)
                .orderByDesc(ApiLog::getGmtCreated);
        IPage<ApiLog> page = apiLogMapper.selectPage(pageable, wrapper);
        Page<ApiLogDTO> resultPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<ApiLogDTO> dataList = page.getRecords().stream().map(po -> new ApiLogDTO(po)).collect(Collectors.toList());
        resultPage.setRecords(dataList);
        return resultPage;
    }

    /**
     * 根据序列号查询日志
     * @param serialNo
     * @return
     */
    public ApiLog getBySerialNo(String serialNo) {
        QueryWrapper<ApiLog> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(ApiLog::getSerialNo, serialNo);
        return apiLogMapper.selectOne(wrapper);
    }

    /**
     * 存储日志
     * @param apiLog
     */
    public void save(ApiLog apiLog) {
        apiLogMapper.insert(apiLog);
    }

    /**
     * 更新调用结果
     * @param id
     * @param responseCode
     * @param endTime
     */
    public void updateResult(Integer id, Integer responseCode, LocalDateTime endTime) {
        try {
            ApiLog apiLog = apiLogMapper.selectById(id);
            if (apiLog != null) {
                // 计算调用耗时
                Duration duration = Duration.between(apiLog.getStartTime(), endTime);
                UpdateWrapper<ApiLog> updateWrapper = new UpdateWrapper<>();
                updateWrapper.lambda().set(ApiLog::getEndTime, endTime)
                        .set(ApiLog::getResponseCode, responseCode)
                        .set(ApiLog::getElapsedTime, duration.toMillis())
                        .eq(ApiLog::getId, id);
                apiLogMapper.update(null, updateWrapper);
            }
        } catch (Exception ex) {
            log.error("更新日志信息异常", ex);
        }
    }

}
